﻿using UnityEngine;
using System.Collections;

public class scBirdAction : MonoBehaviour {

	public GameObject birdCrash;
	public const float powerConst = 15.0f;
	//[HideInInspector]
	public const float destroyTimeConst = 5.0f;

	
	enum BirdStatus
	{
		Drop = 0,
		Fly,	
		Idle,
		Ready,
		Drag,
		DestroyReserved,
		
		Count
	}
	
	enum BirdType
	{
		RedBird,
		YellowBird,
		ThreeBird,
		BombBird,
		
		Count
	}
	
	enum BirdAniType
	{
		ani1 = 1,
		ani2,
		ani3,
		ani4,
		ani5,
		ani6,
		ani7,
		ani8,
		
		Count
	}
	
	
	private GameObject gameManager;
	private GameObject catapultObject;
	private Animator anim;
	private Vector4 catapultReadyPoint;
	private BirdType birdType;
	private BirdStatus currentBirdStatus = BirdStatus.Idle;
	
	private float powerBird;
	private float angleBird;
	private float beforeDistance = 0;
	private float hitDamage = 100.0f;
	private bool isAnimationLoop = true;

	private float destroyReservedTime = 0.0f;


	// Use this for initialization
	void Start () {
		_InitBird();
	}
	
	// Update is called once per frame
	void Update () {
		_CheckAliveBird();
	}

	void OnMouseDrag()
	{
		_ReloadBird();
	}
	
	void OnMouseUp()
	{
		_FireBird();
	}
	
	void OnCollisionEnter2D(Collision2D coll)
	{
		_CrashBird(coll.gameObject);
	}


	void SetReady(Vector4 readyPoint)
	{
		_SetBirdStatusAnimation(BirdStatus.Ready);
		
		catapultReadyPoint = readyPoint;

		iTween.MoveTo(gameObject, iTween.Hash("x", catapultReadyPoint.x, "y", catapultReadyPoint.y, "easeType", "easeOutBack", "time", 1.0f));

		_RigidBodyOnOff(true, 0);
	}


	void _InitBird()
	{
		gameManager = GameObject.Find("GameManager");
		if (gameManager == null)
		{
			return;
		}
		catapultObject = GameObject.Find("pfCatapult");
		if (catapultObject == null)
		{
			return;
		}
		anim = GetComponent<Animator>();
		if (anim == null)
		{
			return;
		}
		
		_RigidBodyOnOff(false);
		
		if (this.name == "pfYellowBird")
		{
			birdType = BirdType.YellowBird;
		}
		else if (this.name == "pfThreeBird")
		{
			birdType = BirdType.YellowBird;
		}
		else if (this.name == "pfBombBird")
		{
			birdType = BirdType.YellowBird;
		}
		else
		{
			birdType = BirdType.RedBird;
		}
		
		StartCoroutine(_AnimationTimer(Random.Range(0.5f, 1.0f)));
	}

	void _ReloadBird()
	{
		if (scGameManager.GetCurrentGameStatus() != scGameManager.GameStatus.Playing)
		{
			return;
		}

		if (currentBirdStatus == BirdStatus.Ready || currentBirdStatus == BirdStatus.Drag)
		{
			currentBirdStatus = BirdStatus.Drag;
			
			Vector3 dragPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
			dragPoint.z = transform.position.z;
			
			//Debug.Log(dragPoint);
			
			_MoveBirdInCircle(dragPoint);
			_CalculatePower(dragPoint);
			_CalculateAngle(dragPoint);
		}
	}

	void _FireBird()
	{
		if (currentBirdStatus != BirdStatus.Drag)
		{
			return;
		}
		
		if (powerBird < 0.4f)
		{
			Debug.Log("need more power!!! reset position");
			
			_SetBirdStatusAnimation(BirdStatus.Ready);
			
			transform.position = catapultReadyPoint;
			
			return;
		}

		_SetBirdStatusAnimation(BirdStatus.Fly);
		
		_RigidBodyOnOff(true, 1f);
		
		rigidbody2D.velocity = Quaternion.Euler(Vector3.forward * angleBird) * Vector2.right * powerBird * powerConst;
		
		gameManager.SendMessage("BeginBirdPath", transform, SendMessageOptions.DontRequireReceiver);
		gameManager.SendMessage("SetNextBird", SendMessageOptions.DontRequireReceiver);
	}

	void _CrashBird(GameObject collisionObject)
	{
		if (currentBirdStatus == BirdStatus.Fly)
		{
			_SetBirdStatusAnimation(BirdStatus.Drop);
			
			gameManager.SendMessage("StopBirdPath", SendMessageOptions.DontRequireReceiver);
			
			hitDamage = 100.0f;
			
			//rigidbody2D.drag = 1.0f;
			//rigidbody2D.angularDrag = 1.0f;
			//rigidbody2D.angularVelocity = 0.5f;
			rigidbody2D.velocity = Vector2.right * 0.1f;
		}
		else
		{
			hitDamage = Mathf.Max(hitDamage / 1.5f, 1.0f);
		}
		
		if (hitDamage > 9)
		{
			// crash animation.
			Quaternion randomRotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
			Instantiate(birdCrash, transform.position, randomRotation);
		}
		
		if (collisionObject.tag == "Block")
		{
			collisionObject.SendMessage("ApplyDamage", hitDamage, SendMessageOptions.DontRequireReceiver);
		}
		
		StartCoroutine(_BirdDestoryReserve());
	}
	
	IEnumerator _BirdDestoryReserve()
	{
		_SetBirdStatusAnimation(BirdStatus.DestroyReserved);
		
		destroyReservedTime = Time.realtimeSinceStartup + destroyTimeConst - 0.1f;
		
		yield return new WaitForSeconds(destroyTimeConst);
		
		if (destroyReservedTime <= Time.realtimeSinceStartup)
		{
			Destroy(gameObject);

			gameManager.SendMessage("DiedBird");
		}
	}

	void _CheckAliveBird()
	{
		if (currentBirdStatus == BirdStatus.Fly || currentBirdStatus == BirdStatus.Drop)
		{
			Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(transform.position);
			//Debug.Log(targetScreenPos);
			if (targetScreenPos.x > Screen.width || targetScreenPos.x < 0 || targetScreenPos.y < 0)
			{
				if (currentBirdStatus == BirdStatus.Fly)
				{
					gameManager.SendMessage("StopBirdPath", SendMessageOptions.DontRequireReceiver);
				}
				
				StartCoroutine(_BirdDestoryReserve());
			}
		}
	}

	void _RigidBodyOnOff(bool isOn, float ifOnGravity = 0f)
	{
		if (isOn)
		{
			rigidbody2D.gravityScale = ifOnGravity;
			//rigidbody2D.collider2D.enabled = true;
			rigidbody2D.collider2D.isTrigger = false;
		}
		else
		{
			rigidbody2D.gravityScale = 0f;
			//rigidbody2D.collider2D.enabled = false;
			rigidbody2D.collider2D.isTrigger = true;
		}
	}
	
	void _SetBirdStatusAnimation(BirdStatus birdStatus)
	{
		currentBirdStatus = birdStatus;

		if (birdStatus == BirdStatus.Idle)
		{
			anim.SetInteger("BirdAniType", Random.Range((int)BirdAniType.ani1, (int)BirdAniType.Count));
		}
		else if (birdStatus == BirdStatus.Ready || birdStatus == BirdStatus.Drag)
		{
			anim.SetInteger("BirdAniType", Random.Range((int)BirdAniType.ani1, (int)BirdAniType.ani5));
		}
		else if (birdStatus == BirdStatus.Fly)
		{
			isAnimationLoop = false;
			anim.SetTrigger("BirdFly");
		}
		else if (birdStatus == BirdStatus.Drop)
		{
			isAnimationLoop = false;
			anim.SetTrigger("BirdDrop");
		}
	}
	
	IEnumerator _AnimationTimer(float delayTime)
	{
		yield return new WaitForSeconds(delayTime);
		
		if (isAnimationLoop)
		{
			_SetBirdStatusAnimation(currentBirdStatus);
		
			StartCoroutine(_AnimationTimer(Random.Range(0.5f, 1.0f)));
		}
	}

	void _MoveBirdInCircle(Vector3 worldPoint)
	{
		float tmpX = worldPoint.x - catapultReadyPoint.x;
		float tmpY = worldPoint.y - catapultReadyPoint.y;
		float distance = Mathf.Sqrt(tmpX * tmpX + tmpY * tmpY);
		
		if (distance > catapultReadyPoint.w)
		{
			Vector3 newPoint = worldPoint;
			float radian = Mathf.Atan2(tmpY, tmpX);
			newPoint.x = catapultReadyPoint.x + catapultReadyPoint.w * Mathf.Cos(radian);
			newPoint.y = catapultReadyPoint.y + catapultReadyPoint.w * Mathf.Sin(radian);
			
			transform.position = newPoint;
		}
		else
		{
			transform.position = worldPoint;
		}

		float reloadDistance = Mathf.Min(distance, catapultReadyPoint.w);
		if (reloadDistance > beforeDistance)
		{
			catapultObject.SendMessage("PlayAudioReloadBird");
		}

		beforeDistance = reloadDistance;
	}
	
	void _CalculatePower(Vector3 worldPoint)
	{
		powerBird = Mathf.Min( 
			Mathf.Sqrt(Mathf.Pow((worldPoint.x - catapultReadyPoint.x), 2) + Mathf.Pow((worldPoint.y - catapultReadyPoint.y), 2)),
			catapultReadyPoint.w
			);
		
		//Debug.Log("파워는 : " + powerBird);
	}
	
	void _CalculateAngle(Vector3 worldPoint)
	{
		float tmpX = worldPoint.x - catapultReadyPoint.x;
		float tmpY = worldPoint.y - catapultReadyPoint.y;		
		float radian = Mathf.Atan2(tmpY, tmpX);
		float degree = radian * 180.0f / 3.14159265f;		
		
		angleBird = degree + 180.0f;
		//Debug.Log("각도는 : " + angleBird);
	}
}
